/*
 * CacheUtils.java
 * business
 *
 * Created by ChenTao on 2016/9/9.
 *
 * Copyright (c) 2016年 yidiandao. All rights reserved.
 */

package com.yidiandao.business.utils;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build.VERSION_CODES;
import android.os.Environment;
import android.text.TextUtils;

import com.yidiandao.business.constant.Common;

import java.io.File;
import java.math.BigDecimal;

/**
 * 缓存工具.
 */
public final class CacheUtils {

    /**
     * 缓存工具.
     */
    private CacheUtils() {
    }

    /**
     * 获取内存缓存的大小, 取应用可用内存的1/5作为内存缓存.
     *
     * @return 内存缓存的大小, 单位字节
     */
    public static int getMemCacheSize(final Context context) {
        if (context == null) {
            throw new NullPointerException("context不能为空");
        }
        return (int) (Runtime.getRuntime().maxMemory() / 1024 / 8);
    }

    /**
     * 获取磁盘缓存的大小, 大小为50MB.
     *
     * @param context Context
     * @return 磁盘缓存的大小
     */
    public static int getDiskCacheSize(final Context context) {
        if (context == null) {
            throw new NullPointerException("context不能为空");
        }
        return 1024 * 1024 * 50;
    }

    /**
     * 获取外部的应用缓存目录.
     *
     * @param context Context
     * @return 外部缓存目录
     */
    @TargetApi(VERSION_CODES.FROYO)
    public static File getExternalCacheDir(final Context context) {
        if (context == null) {
            throw new NullPointerException("context不能为空");
        }
        if (SysUtils.hasFroyo()) {
            File cacheDir = context.getExternalCacheDir();
            if (cacheDir != null) {
                return cacheDir;
            }
        }
        final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
        return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
    }

    /**
     * 获取应用目录，当SD卡存在时，获取SD卡上的目录，当SD卡不存在时，获取应用的cache目录
     *
     * @param context Context
     * @return 缓存目录
     */
    public static File getAppCacheDir(final Context context) {
        if (context == null) {
            throw new NullPointerException("context不能为空");
        }
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !FileUtils.isExternalStorageRemovable()
                ? CacheUtils.getExternalCacheDir(context)
                : context.getCacheDir();
    }

    public static File getAppCacheDir(final Context context, String uniqueName) {
        File appCacheDir = getAppCacheDir(context);
        return new File(appCacheDir + File.separator + uniqueName);
    }

    /**
     * 获取接口数据缓存文件夹的地址
     */
    private static File getServerDataCacheDir(Context context) {
        File serverDataCacheFile = CacheUtils.getAppCacheDir(context, Common.SERVER_DATA_DIR_NAME);
        if (!serverDataCacheFile.exists()) {
            serverDataCacheFile.mkdirs();
        }

        return serverDataCacheFile;
    }

    /**
     * 获取接口数据缓存文件的地址
     */
    private static File getServerDataCacheFile(Context context, String interfaceName) {
        File serverDataCacheDir = CacheUtils.getServerDataCacheDir(context);
        // 接口名+uid
        String fileName =
                Md5Utils.getMD5String(
                        interfaceName + PreferenceUtils.getUserId(UIUtils.getContext()));
        File cacheFile = null;
        if (!TextUtils.isEmpty(fileName)) {
            cacheFile = new File(serverDataCacheDir, fileName);
        }
        return cacheFile;
    }

    /**
     * 存储缓存
     *
     * @param fileName 缓存文件名称
     * @param json     存储的json数据
     */
    public static void saveDataToDisk(String fileName, String json) {
        File cacheFile = CacheUtils.getServerDataCacheFile(UIUtils.getContext(), fileName);
        FileUtils.writeFile(json, cacheFile.getAbsolutePath());
    }

    /**
     * 读取缓存
     *
     * @param fileName 缓存文件名称
     * @return 缓存
     */
    public static String getDataFromDisk(String fileName) {
        File cacheFile = CacheUtils.getServerDataCacheFile(UIUtils.getContext(), fileName);
        return FileUtils.readFile(cacheFile.getAbsolutePath());
    }

    /**
     * @return 获取总缓存大小
     */
    public static String getTotalCacheSize(Context context) throws Exception {
        long cacheSize = getFolderSize(context.getCacheDir());
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            cacheSize += getFolderSize(context.getExternalCacheDir());
        }
        return getFormatSize(cacheSize);
    }

    /**
     * 清除缓存
     */
    public static void clearAllCache(Context context) {
        deleteDir(context.getCacheDir());
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            deleteDir(context.getExternalCacheDir());
        }
    }

    private static boolean deleteDir(File dir) {
        if (dir != null && dir.isDirectory()) {
            String[] children = dir.list();
            for (String child : children) {
                boolean success = deleteDir(new File(dir, child));
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }

    // 获取文件
    //Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/ 目录，一般放一些长时间保存的数据
    //Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录，一般存放临时缓存数据
    public static long getFolderSize(File file) {
        long size = 0;
        try {
            File[] fileList = file.listFiles();
            for (File childFile : fileList) {
                // 如果下面还有文件
                if (childFile.isDirectory()) {
                    size = size + getFolderSize(childFile);
                } else {
                    size = size + childFile.length();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    /**
     * 格式化单位
     */
    public static String getFormatSize(double size) {
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
            //            return size + "Byte";
            return "0K";
        }

        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "K";
        }

        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "M";
        }

        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "G";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "T";
    }
}
